package com.exam.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.exam.entity.po.Role;
import com.exam.entity.po.User;
import com.exam.entity.vo.Result;
import com.exam.entity.vo.Token;
import com.exam.service.RoleService;
import com.exam.service.UserService;
import com.exam.util.*;
import io.swagger.annotations.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Base64Utils;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @Des 角色接口
 * @Author ymj
 * @Date 2021/9/2 18:35
 */

@RestController
@CrossOrigin
@RequestMapping("/demo/role")
@Slf4j
@Api(tags = "角色相关接口", description = "提供角色相关的API接口")
public class RoleController {

    @Autowired
    private UserService userService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private RedisUtil redisUtil;


    @ApiOperation(value = "打印用户实体并返回")
    @GetMapping("/getUser")
    public User getUser(User user) {
        return user;
    }

    @ApiOperation("用户注册接口")
    @PostMapping("/register")
    public Result Register(@RequestBody User user) throws NoSuchAlgorithmException {
        //检查用户名是否重名
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername());
        User dbUser = userService.getOne(wrapper);
        if (dbUser != null) return Result.error("用户已存在");

        //盐值
        String salt = UUID.randomUUID().toString().substring(0, 6);
        String newPwd = SaltEncryption.saltEncryption(user.getPassword(), salt);
        user.setPassword(newPwd);
        user.setSalt(salt);
        //设置加密
        userService.save(user);
        return Result.success();
    }

    @ApiOperation("验证码生成接口")
    @GetMapping("/getImage")
    public Map<String, String> getImage(HttpServletRequest request) throws IOException {
        Map<String, String> result = new HashMap<>();
        CreateImageCode createImageCode = new CreateImageCode();
        //获取验证码
        String securityCode = createImageCode.getCode();
        //验证码存入session
        String key = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        request.getServletContext().setAttribute(key, securityCode);
        //生成图片
        BufferedImage image = createImageCode.getBuffImg();
        //进行base64编码
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ImageIO.write(image, "png", bos);
        String string = Base64Utils.encodeToString(bos.toByteArray());
        result.put("key", key);
        result.put("image", string);
        result.put("true_code", securityCode);
        return result;
    }

    @PostMapping("/login")
    @ApiOperation("用户登录接口")
    public Result login(@RequestBody User user) throws NoSuchAlgorithmException {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("username", user.getUsername());
        User dbUser = userService.getOne(wrapper);
        if (dbUser != null) {
            String newPwd = SaltEncryption.saltEncryption(user.getPassword(), dbUser.getSalt());
            //对比数据库的密码 确认用户的状态是否正常
            if (newPwd.equals(dbUser.getPassword()) && dbUser.getStatus() == 1) {
                //发放token令牌
                String token = TokenUtils.createToken(new Token(dbUser.getRoleId() + "", dbUser.getUsername(), newPwd));
                return Result.success(token);
            } else {//密码错误 或者 用户状态异常
                return Result.error("账号密码错误,或用户状态异常");
            }
        }
        //用户不存在
        else return Result.error("用户不存在");
    }

    @GetMapping("/checkToken")
    @ApiOperation("验证用户token接口")
    public Result checkToken(HttpServletRequest request) {
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        Token token = new CheckToken().checkToken(request, userService);
        if (token != null) {//有效token
            return Result.success(token);
        } else {
            return Result.error("token无效");
        }
    }

    @GetMapping("/getMenu")
    @ApiOperation(value = "获取不同用户的权限菜单")
    public Result getMenu(HttpServletRequest request) {
        //工具类验证token是否有效 有效返回tokenVo对象,否则返回null
        Token token = new CheckToken().checkToken(request, userService);
        if (token != null) {//有效token
            if (redisUtil.get("menu:" + token.getRoleId()) != null) {
                return Result.success(redisUtil.get("menu:" + token.getRoleId()));
            } else {
                String roleId = token.getRoleId();
                QueryWrapper<Role> wrapper = new QueryWrapper<>();
                wrapper.eq("role_id", roleId);
                Role role = roleService.getOne(wrapper);
                redisUtil.set("menu:" + token.getRoleId(), role.getMenuInfo(), 60 * 60 * 10 + new Random().nextInt(5) * 60 * 60);
                return Result.success(role.getMenuInfo());
            }

        } else {
            return Result.error("认证信息有误,获取数据失败");
        }
    }
    @GetMapping("/getRoleMessage")
    @ApiOperation(value = "获取角色信息")
    @ApiImplicitParam(name = "username", value = "角色用户名", required = true, dataType = "string", paramType = "body")
    public Result getRoleMessage(String username){
        User user = (User)redisUtil.get("user:"+username);
        if (user!=null){
            return Result.success(user);
        }else{
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.eq("username",username);
            user = userService.getOne(wrapper);
            if (user!=null){
                redisUtil.set("user:"+username,user,60 * 60 * 10 + new Random().nextInt(5) * 60 * 60);
                return Result.success(user);
            }else{
                return Result.error("查无此人");
            }
        }
    }
}
